﻿using System;

public class Bufor
{
    long rozmiar;//pojemność na razie w il.paczek potem bitów
    int zajety_rozmiar;
    public string nazwa;
    public SredniaZajetosc srednia_zajetosc;
    public int zdarzenia_odrzucone; // dane statystyczne o odrzuconych pakietach
    public int zdarzenia_zaakceptowane; // dane statystyczne o przyjętych 

    Czasomierz czasomierz;
    Drzewo<Pakiet> fifo;//kontener używany przez bufor
    public Bufor(string nazwa, long rozmiar)//size - pojemność bufora
    {
        czasomierz = new Czasomierz();
        srednia_zajetosc = new SredniaZajetosc();
        this.nazwa = nazwa;
        this.rozmiar = rozmiar;
        zajety_rozmiar = 0;
        fifo = new Drzewo<Pakiet>();
        zdarzenia_odrzucone = 0; // nic jeszcze nie odrzuciliśmy
        zdarzenia_zaakceptowane = 0; // nic jeszcze nie przyjeliśmy
    }
    public bool JestPelny()
    {
        if (zajety_rozmiar == rozmiar)
            return true;
        else
            return false;
    }
    public bool JestPusty()
    {
        if (zajety_rozmiar == 0)
            return true;
        else
            return false;
    }
    public void Insert(Pakiet p, double obecny_czas = 0)
    {
        double waga = czasomierz.stop(obecny_czas);
        czasomierz.start(obecny_czas);
        fifo.Insert(p);
        zajety_rozmiar++;
        srednia_zajetosc.DodajDoSredniej(zajety_rozmiar, waga);
    }
    public Pakiet ZwrocMin()
    {
        return fifo.ZwrocMin();
    }
    public void UsunMin()
    {
        Pakiet temp = fifo.ZwrocMin();
        fifo.DeleteMin();
        zajety_rozmiar--;
    }
    public Pakiet WezIUsunMin(double obecny_czas = 0)
    {
        Pakiet p = fifo.ZwrocMin();
        fifo.DeleteMin();
        zajety_rozmiar--;
        double weight = czasomierz.stop(obecny_czas);
        czasomierz.start(obecny_czas);
        srednia_zajetosc.DodajDoSredniej(zajety_rozmiar, weight);
        return p;
    }
    public int WezOczekujace()
    {
        return zdarzenia_odrzucone;
    }
    public int WezZaakceptowane()
    {
        return zdarzenia_zaakceptowane;
    }
    public void accept()
    {
        zdarzenia_zaakceptowane++;
    }
    public void reject()
    {
        zdarzenia_odrzucone++;
    }
    public string getStatistic()
    {
        //fifo.Show();
        double prawdopodobienstwo_odrzucenia = ((double)1000 * zdarzenia_odrzucone / (zdarzenia_odrzucone + zdarzenia_zaakceptowane));
        if (prawdopodobienstwo_odrzucenia != 0)
            return "_____Zaakceptowane pakiety: " + zdarzenia_zaakceptowane + "\n_____Odrzucone pakiety:" + zdarzenia_odrzucone + "\n_____Prawdopodobieństwo odrzucenia: " + String.Format("{0:N2}", prawdopodobienstwo_odrzucenia) + "‰" + "\n_____Średnia zajętość bufora: " + srednia_zajetosc.WezSrednia() + " bajtów";
        else
            return "_____Zaakceptowane pakiety: " + zdarzenia_zaakceptowane + "\n_____Odrzucone pakiety:" + zdarzenia_odrzucone + "\n_____Prawdopodobieństwo odrzucenia: " + prawdopodobienstwo_odrzucenia + "‰" + "\n_____Średnia zajętość bufora: " + srednia_zajetosc.WezSrednia() + " bajtów";
    }

    public bool HaveSize(Pakiet p)
    {
        if (rozmiar - zajety_rozmiar >= p.rozmiar) return true;
        else return false;
    }
}

